package com.woniu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.entity.Atten;
import com.woniu.entity.vo.AttenVo;
import com.woniu.entity.vo.PageResponseVo;
import com.woniu.mapper.AttenMapper;
import com.woniu.mapper.UserMapper;
import com.woniu.service.IAttenService;
import com.woniu.util.DateUtils;
import com.woniu.util.EmptyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.transaction.annotation.Transactional;


import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Stream;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hyl
 * @since 2022-08-28
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class AttenServiceImpl extends ServiceImpl<AttenMapper, Atten> implements IAttenService {
    @Autowired
    private AttenMapper attenMapper;
    @Autowired
    private UserMapper userMapper;

    private static final String START_WORK_TIME = " 09:00:00";
    private static final String END_WORK_TIME = " 17:00:00";

    /**
     * 考勤签到
     *
     * @param attenVo
     * @return
     * @throws ParseException
     */
    @Override
    public String signIn(AttenVo attenVo) throws ParseException {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 上班时间
        String workTime = attenVo.getAtten().getAttenDate() + START_WORK_TIME;
        // 下班时间
        String lifeTime = attenVo.getAtten().getAttenDate() + END_WORK_TIME;
        Date currentTime = dateFormat.parse(attenVo.getCurrentTime());
        // 基准上班时间
        Date baseWorkTIme = dateFormat.parse(workTime);
        // 基准下班时间
        Date baseLifeTIme = dateFormat.parse(lifeTime);
        Atten atten = attenVo.getAtten();
        // 当天打卡情况
        Atten dayCondition = attenMapper.getByUserIdAndAttenDate(attenVo.getAtten().getUserId(), attenVo.getAtten().getAttenDate());

        if (dayCondition == null) {
            attenVo.getAtten().setStartTime(attenVo.getCurrentTime());
            if (currentTime.getTime() <= baseWorkTIme.getTime()
                    && currentTime.getTime() > dateFormat.parse(DateUtils.getSpecifiedHour(workTime, -1)).getTime()) {
                atten.setAttenStatusOn("正常"); // 8-9点打卡正常
            } else if (currentTime.getTime() > baseWorkTIme.getTime()
                    && currentTime.getTime() >= dateFormat.parse(DateUtils.getSpecifiedHour(workTime, 3)).getTime()) {
                atten.setAttenStatusOn("迟到"); // 9-12点打卡迟到
            } else if (currentTime.getTime() >= dateFormat.parse(DateUtils.getSpecifiedHour(workTime, 3)).getTime()
                    && currentTime.getTime() < baseLifeTIme.getTime()) {
                atten.setAttenStatusOn("旷工"); // 12点以后到17点前打卡旷工
            } else {
                return "该时段内打卡无效";
            }
            attenMapper.insert(atten);
            return atten.getAttenStatusOn();
        } else {
            if (currentTime.getTime() > dateFormat.parse(dayCondition.getStartTime()).getTime()
                    && currentTime.getTime() < dateFormat.parse(DateUtils.getSpecifiedHour(workTime, 1)).getTime()) {
                return "请勿重复打卡"; // 上班卡打完到10点
            } else if (currentTime.getTime() >= dateFormat.parse(DateUtils.getSpecifiedHour(workTime, 1)).getTime()
                    && currentTime.getTime() < baseLifeTIme.getTime()) {
                dayCondition.setAttenStatusOff("早退"); // 上班卡打完 10点到17点打卡早退
                dayCondition.setEndTime(attenVo.getCurrentTime());
                attenMapper.updateAttendance(dayCondition);
                return dayCondition.getAttenStatusOff();
            } else if (currentTime.getTime() >= baseLifeTIme.getTime()
                    && currentTime.getTime() <= dateFormat.parse(DateUtils.getSpecifiedHour(lifeTime, 7)).getTime()
                    && dayCondition.getAttenStatusOff() == null) {
                dayCondition.setAttenStatusOff("正常"); // 17-24点且下班卡状态为空正常
                dayCondition.setEndTime(attenVo.getCurrentTime());
                attenMapper.updateAttendance(dayCondition);
                return dayCondition.getAttenStatusOff();
            } else {
                return "该时段内打卡无效";
            }
        }

    }

    @Override
    public void update(Atten atten) {
        attenMapper.updateAttendance(atten);
    }

    @Override
    public PageResponseVo<Atten> getAttenPage(Integer page, Integer count) {
        Page<Atten> pager = new Page<>(page, count);

        IPage<Atten> paging = this.getBaseMapper().selectPage(pager, null);
        return new PageResponseVo(paging.getTotal(), paging.getRecords(), paging.getCurrent(), paging.getSize());
    }

    /**
     * 多条件分页查询考勤状态
     * authot ConstantinD
     *
     * @param page
     * @param count
     * @param atten
     * @return
     */
    @Override
    public PageResponseVo<Atten> getAttenPageByTerms(Integer page, Integer count, Atten atten) {
        Page<Atten> pager = new Page<>(page, count);
        QueryWrapper<Atten> queryWrapper = new QueryWrapper<>();
        if (EmptyUtil.isEmpty(atten)){
            queryWrapper.eq("1","1");
        }
        if (EmptyUtil.isNoEmpty(atten.getUserId())) {
            queryWrapper.eq("atten.user_id", atten.getUserId());
//            atten.setUser(userMapper.getByUserId(atten.getUserId()));
        }
        if(EmptyUtil.isNoEmpty(atten.getUser())){
            queryWrapper.eq("user.user_name",atten.getUser().getUserName());
        }
        if (EmptyUtil.isNoEmpty(atten.getAttenDate())) {
            queryWrapper.eq("atten_date", atten.getAttenDate());
        }
        if (EmptyUtil.isNoEmpty(atten.getStartAttenDate()) && EmptyUtil.isNoEmpty(atten.getEndAttenDate())) {
            queryWrapper.between("atten_date", atten.getStartAttenDate(), atten.getEndAttenDate());
        }
        if(EmptyUtil.isNoEmpty(atten.getDept())){
            queryWrapper.eq("user.dept_id",atten.getDept().getDeptId());
        }
        IPage<Atten> paging = attenMapper.getAttenWithPage(pager, queryWrapper);
        return new PageResponseVo<>(paging.getTotal(), paging.getRecords(), paging.getCurrent(), paging.getSize());
    }

    /**
     * 更新全天未打卡考勤状态
     *
     * @param date
     * @return
     */
    @Override
    public Integer updateNotAttenAllDay(String date) {
        List<Integer> attenUserId = attenMapper.getUserIdByAttenDate(date);
        List<Integer> userId = new ArrayList<>();
        userMapper.getByAnyUser(null).stream().forEach(e -> {
            userId.add(e.getUserId());
        });//TODO 根据用户状态查出来的userIdList
        List<Integer> lackAttenUserId = new ArrayList<>();
        for (Integer uid : userId) {
            if (!attenUserId.contains(uid)) {
                Atten attendance = new Atten();
                lackAttenUserId.add(uid);
                attendance.setUserId(uid);
                attendance.setAttenDate(date);
                attendance.setAttenStatusOn("旷工");
                attendance.setAttenStatusOff("旷工");
                attenMapper.insert(attendance);
            }
        }
        return lackAttenUserId.size();
    }

    /**
     * 更新下午未打卡考勤状态
     *
     * @param date
     * @return
     */
    @Override
    public Integer updateNotAttenOffWork(String date) {
        List<Atten> attenList = attenMapper.getOffWorkNotAttenByDate(date);
        attenList.stream().forEach(e -> {
            e.setAttenStatusOff("旷工");
            attenMapper.updateAttendance(e);
        });
        return attenList.size();
    }


}
